module counter (
			// inputs:
			iclk,
			ireset,
			ispeed,
			iHS,
			iVS,
			iendx,
			iendy,

			// outputs:
			oxoffset,
			oyoffset	
             );


input	iclk, ireset, iHS, iVS;
input	[13:0]	ispeed;
input [8:0]	iendx, iendy;
output	[8:0]	oxoffset, oyoffset;

reg	signed [8:0]	xoffset,yoffset;
assign oxoffset = xoffset;
assign oyoffset = yoffset;

(* preserve *)reg	[3:0]	state;
reg 	[13:0]	count;
wire	[9:0] 	diffx,diffy;

wire	[9:0]	dx, dy;
reg	[8:0]	temp,  x, y;
reg [9:0]	tempdx, tempdy;
reg	xchange;
reg	[9:0]	half;

assign	diffx = iendx-xoffset;
assign dx = (diffx[9])? -diffx:diffx;
assign	diffy = iendy-yoffset;
assign dy = (diffy[9])? -diffy:diffy;

//state names
parameter	init		= 4'd0,
		drawline1	= 4'd1,
		drawline2	= 4'd2,
		drawline3	= 4'd3,
		drawline4	= 4'd4;

always @ (posedge iclk)
begin
	if (ireset)
	begin
		xoffset <= 9'd160;
		yoffset <= 9'd120;
	end
	else if (~iHS | ~iVS)
	begin
		case(state)
			init:
			begin
				if ((xoffset != iendx) || (yoffset != iendy))
				begin
					count <= count + 1'd1;
					// find next pixel's coordinate according to end point's direction relative to starting point
					if (count >= ispeed)	
					begin
						count <= 1'd0;
						x <= xoffset;
						y <= yoffset;
						tempdx <= dx;
						temp <= dx;
						tempdy <= dy;
						xchange <= 1'd0;
						half <= 10'd0;

						state <= drawline1;
					end
				end
			end
			
			drawline1:
			begin
				if(tempdy > tempdx)
				begin
					tempdx <= dy;
					tempdy <= temp;
					xchange <= 1'd1;
				end
				state <= drawline2;
			end
			
			drawline2:
			begin
				half <= (tempdy << 1) - tempdx;
				state <= drawline3;
			end
			
			drawline3:
			begin
				if (~half[9])
				begin
					if (xchange)
					begin
						if (diffx[9])
							x <= x-1'd1;
						else
							x <= x+1'd1;
					end
					else	
					begin
						if (diffy[9])
							y <= y-1'd1;
						else
							y <= y+1'd1;
					end
					half <= half-(tempdx << 1);
				end

				else
				begin
					if (xchange) 
					begin
						if (diffy[9])
							y <= y-1'd1;
						else
							y <= y+1'd1;
					end
					else	
					begin
						if (diffx[9])
							x <= x-1'd1;
						else
							x <= x+1'd1;
					end
					half <= half+(tempdy << 1);
				end
				state <= drawline4;
			end
			
			drawline4:
			begin
				state <= init;
				xoffset <= x;
				yoffset <= y;
			end
		endcase
	end
	
end

endmodule				
			

